<template>
  <div class="sc-upload-multiple">
    <el-upload
      ref="uploader"
      list-type="picture-card"
      :auto-upload="cropperable ? false : autoUpload"
      :disabled="disabled"
      drag
      :action="action"
      :name="name"
      :data="data"
      :http-request="request"
      v-model:file-list="defaultFileList"
      :show-file-list="showFileList"
      :accept="accept"
      :multiple="multiple"
      :limit="limit"
      :before-upload="before"
      :on-success="success"
      :on-error="error"
      :on-preview="handlePreview"
      :on-exceed="handleExceed"
      :on-change="change"
    >
      <div class="el-upload__f">
        <div v-if="showbutton && !disabled">
          <el-tooltip content="手机上传">
            <el-icon
              @click="showQrCode"
              @mouseenter="iconColor = '#409EFC'"
              :size="30"
              @mouseleave="iconColor = 'inherit'"
            >
              <el-icon-iphone :color="iconColor" />
            </el-icon>
          </el-tooltip>
          <el-tooltip content="先点击然后按CTRL + v">
            <el-icon
              @mouseleave="iconColor1 = 'inherit'"
              @click="
                (e) => {
                  iconColor1 = '#409EFC';
                  this.$refs.uploadPaste.focus();
                  e.stopPropagation();
                }
              "
              :size="30"
            >
              <el-icon-documentCopy :color="iconColor1" />
            </el-icon>
          </el-tooltip>
          <el-tooltip content="选择已上传">
            <el-icon
              @click="handleChoose"
              @mouseenter="iconColor2 = '#409EFC'"
              :size="30"
              @mouseleave="iconColor2 = 'inherit'"
            >
              <el-icon-Upload :color="iconColor2" />
            </el-icon>
          </el-tooltip>
        </div>
      </div>

      <template #tip>
        <div v-if="tip" class="el-upload__tip">{{ tip }}</div>
      </template>
      <template #file="{ file }">
        <div class="sc-upload-list-item">
          <el-image
            class="el-upload-list__item-thumbnail"
            :src="file.url"
            fit="cover"
            :preview-src-list="preview"
            :initial-index="preview.findIndex((n) => n == file.url)"
            hide-on-click-modal
            append-to-body
            :z-index="9999"
          >
            <template #placeholder>
              <div class="sc-upload-multiple-image-slot">Loading...</div>
            </template>
          </el-image>
          <div
            v-if="!disabled && file.status == 'success' && allow_delete"
            class="sc-upload__item-actions"
          >
            <span class="del" @click="handleRemove(file)">
              <el-icon>
                <el-icon-delete />
              </el-icon>
            </span>
          </div>
          <div
            v-if="file.status == 'ready' || file.status == 'uploading'"
            class="sc-upload__item-progress"
          >
            <el-progress
              :percentage="file.percentage"
              :text-inside="true"
              :stroke-width="16"
            />
          </div>
        </div>
      </template>
    </el-upload>

    <span style="display: none !important">
      <el-input v-model="value"></el-input>
    </span>
    <el-dialog
      title="剪裁"
      draggable
      v-model="cropperDialogVisible"
      :width="580"
      @closed="cropperClosed"
      destroy-on-close
    >
      <sc-cropper
        :src="cropperFile.tempCropperFile"
        :compress="compress"
        :aspectRatio="aspectRatio"
        ref="cropper"
      ></sc-cropper>
      <template #footer>
        <el-button @click="cropperDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="cropperSave">确 定</el-button>
      </template>
    </el-dialog>
  </div>
  <showqrcode v-if="showqrupload" ref="showqrCode" :text="qrtext" @success="qrupload">
  </showqrcode>
  <skBrowserChoose
    v-if="openChooseDlg"
    v-model="openChooseDlg"
    :name="'attachment'"
    @close="openChooseDlg = false"
    :params="getParams"
    @select="selectchoose"
  ></skBrowserChoose>
  <el-input
    ref="uploadPaste"
    v-on="{ paste: handlePaste }"
    style="margin: -100000px; display: position"
  />
</template>

<script>
import config from "@/config/skupload";
import Sortable from "sortablejs";
import showqrcode from "./showqrcode";
import skBrowserChoose from "@/components/skBrowserChoose";
import tool from "@/utils/tool";
import scCropper from "@/components/scCropper";
export default {
  components: {
    showqrcode,
    scCropper,
    skBrowserChoose,
  },
  props: {
    modelValue: { type: Object, default: () => {} },
    tip: { type: String, default: "" },
    action: { type: String, default: "" },
    apiObj: { type: Object, default: () => {} },
    name: { type: String, default: config.filename },
    data: { type: Object, default: () => {} },
    accept: { type: String, default: "image/gif, image/jpeg, image/png" },
    maxSize: { type: Number, default: config.maxSizeFile },
    limit: { type: Number, default: 2 },
    autoUpload: { type: Boolean, default: true },
    showFileList: { type: Boolean, default: true },
    multiple: { type: Boolean, default: true },
    disabled: { type: Boolean, default: false },
    allow_delete: { type: Boolean, default: true },
    draggable: { type: Boolean, default: false },
    onSuccess: {
      type: Function,
      default: () => {
        return true;
      },
    },
    showbutton: { type: Boolean, default: true },
    cropperable: { type: Boolean, default: false },
    compress: { type: Number, default: 1 },
    aspectRatio: { type: Number, default: NaN },
  },
  data() {
    let ul = window.location.href;
    ul =
      ul.substring(0, ul.indexOf("#")) +
      `#common/upload?temporaryToken=` +
      tool.data.get("TOKEN");
    return {
      value: "",
      qrtext: ul,
      defaultFileList: [],
      showqrupload: false,
      openChooseDlg: false,
      onChangeImgUrl: false,
      cropperDialogVisible: false,
      cropperFile: null,
      iconColor: "inherit",
      iconColor1: "inherit",
      iconColor2: "inherit",
    };
  },
  watch: {
    modelValue(val) {
      if (val.length != this.defaultFileList.length) {
        this.defaultFileList = val;
      }
    },
    defaultFileList: {
      handler(val) {
        if (val.length > 0) this.onChangeImgUrl = true;
        this.$emit("update:modelValue", this.toStr(val));
      },
      deep: true,
    },
    onChangeImgUrl: {
      handler(newName) {
        if (this.limit == 1) {
          var aa = document.querySelector(".el-upload--picture-card");
          if (newName) {
            aa.style.display = "none";
          } else {
            aa.style.display = "inline-block";
          }
        }
      },
    },
  },
  computed: {
    preview() {
      return this.defaultFileList.map((v) => v.url);
    },
  },
  mounted() {
    this.value = this.modelValue;
    this.defaultFileList = this.modelValue;
    if (!this.disabled && this.draggable) {
      this.rowDrop();
    }
  },
  methods: {
    getParams() {
      let user = tool.data.get("USER_INFO");
      return { creator_id: user.id };
    },
    handlePaste(e) {
      var items = "";
      var clipboardData =
        e.clipboardData || e.originalEvent.clipboardData || window.clipboardData;
      // 兼容浏览器
      if (!clipboardData) {
        // 提示说明，此浏览器不支持此操作
        this.$message.error("当前浏览器不支持粘贴上传操作！");
        return;
      }
      items = clipboardData.items;

      let file = null;
      if (!items || items.length === 0) {
        this.$message.error("当前浏览器不支持本地");
        return;
      }
      // 搜索剪切板items
      for (let i = 0; i < items.length; i++) {
        if (items[i].type.indexOf("image") !== -1) {
          file = items[i].getAsFile();
          break;
        }
      }
      if (!file) {
        this.$message.error("粘贴内容非图片");
        return;
      }

      this.$refs.uploader.handleStart(file); // 将粘贴过来的图片加入预上传队列
      this.$refs.uploader.submit(); // 提交图片上传队列
    },
    change(file) {
      // if (files.length > 1) {
      // 	files.splice(0, 1)
      // }
      if (this.cropperable && file.status == "ready") {
        const acceptIncludes = ["image/gif", "image/jpeg", "image/png"].includes(
          file.raw.type
        );
        if (!acceptIncludes) {
          this.$notify.warning({
            title: "上传文件警告",
            message: "选择的文件非图像类文件",
          });
          return false;
        }
        this.cropperFile = file;
        this.cropperFile.tempCropperFile = URL.createObjectURL(file.raw);
        this.cropperDialogVisible = true;
        return false;
      }
      this.file = file;
      if (file.status == "ready") {
        file.tempFile = URL.createObjectURL(file.raw);
      }
    },
    handleChoose(e) {
      e.stopPropagation();
      this.openChooseDlg = true;
    },
    selectchoose(data) {
      (data ?? []).map((v) => (this.defaultFileList[this.defaultFileList.length] = v));
      this.onSuccess(data, data);
      this.openChooseDlg = false;
    },

    cropperSave() {
      this.$refs.cropper.getCropFile(
        (file) => {
          file.uid = this.cropperFile.uid;
          this.cropperFile.raw = file;

          this.file = this.cropperFile;
          this.file.tempFile = URL.createObjectURL(this.file.raw);
          this.$refs.uploader.submit();
        },
        this.cropperFile.name,
        this.cropperFile.type
      );
      this.cropperDialogVisible = false;
    },
    cropperClosed() {
      URL.revokeObjectURL(this.cropperFile.tempCropperFile);
      delete this.cropperFile.tempCropperFile;
    },

    //数组转换为原始值
    toStr(arr) {
      return arr.map((v) => {
        return { id: v.id };
      });
    },
    showQrCode(e) {
      e.stopPropagation();
      console.log(this.qrtext);
      this.showqrupload = true;
      this.$nextTick(() => {
        this.$refs.showqrCode.open();
      });
    },
    qrupload(res) {
      if (res.success) {
        this.defaultFileList[this.defaultFileList.length] = res.data.data.data;
        this.success(res.data.data, res.data.data.data);
      }
    },
    //拖拽
    rowDrop() {
      const _this = this;
      const itemBox = this.$refs.uploader.$el.querySelector(".el-upload-list");
      Sortable.create(itemBox, {
        handle: ".el-upload-list__item",
        animation: 200,
        ghostClass: "ghost",
        onEnd({ newIndex, oldIndex }) {
          const tableData = _this.defaultFileList;
          const currRow = tableData.splice(oldIndex, 1)[0];
          tableData.splice(newIndex, 0, currRow);
        },
      });
    },
    before(file) {
      if (!["image/jpeg", "image/png", "image/gif"].includes(file.type)) {
        this.$message.warning(`选择的文件类型 ${file.type} 非图像类文件`);
        return false;
      }
      const maxSize = file.size / 1024 / 1024 < this.maxSize;
      if (!maxSize) {
        this.$message.warning(`上传文件大小不能超过 ${this.maxSize}MB!`);
        return false;
      }
    },
    success(res, file) {
      console.log(res);
      console.log(file);
      var os = this.onSuccess(res, file);
      if (os != undefined && os == false) {
        return false;
      }
      var response = config.parseData(res);
      file.name = response.fileName;
      file.url = response.url;
      file.id = response.id;
    },
    error(err) {
      this.$notify.error({
        title: "上传文件未成功",
        message: err,
      });
    },
    beforeRemove(uploadFile) {
      return this.$confirm(`是否移除 ${uploadFile.name} ?`, "提示", {
        type: "warning",
      })
        .then(() => {
          return true;
        })
        .catch(() => {
          return false;
        });
    },
    handleRemove(file) {
      this.$refs.uploader.handleRemove(file);
      this.onChangeImgUrl = false;
      //this.defaultFileList.splice(this.defaultFileList.findIndex(item => item.uid===file.uid), 1)
    },
    handleExceed() {
      this.$message.warning(`当前设置最多上传 ${this.limit} 个文件，请移除后上传!`);
    },
    handlePreview(uploadFile) {
      window.open(uploadFile.url);
    },
    request(param) {
      var apiObj = config.apiObj;
      if (this.apiObj) {
        apiObj = this.apiObj;
      }
      const data = new FormData();
      data.append(param.filename, param.file);
      for (const key in param.data) {
        data.append(key, param.data[key]);
      }
      let temporaryToken = tool.data.get("temporaryToken");
      if (temporaryToken) data.append("temporaryToken", tool.data.get("temporaryToken"));
      apiObj
        .post(data, {
          onUploadProgress: (e) => {
            const complete = parseInt(((e.loaded / e.total) * 100) | 0, 10);
            param.onProgress({ percent: complete });
          },
        })
        .then((res) => {
          var response = config.parseData(res);
          if (response.code == config.successCode) {
            param.onSuccess(res);
          } else {
            param.onError(response.msg || "未知错误");
          }
        })
        .catch((err) => {
          param.onError(err);
        });
    },
  },
};
</script>

<style scoped>
.el-form-item.is-error .sc-upload-multiple:deep(.el-upload--picture-card) {
  border-color: var(--el-color-danger);
}

:deep(.el-upload-list__item) {
  transition: none;
  border-radius: 0;
}

.sc-upload-multiple:deep(.el-upload-list__item.el-list-leave-active) {
  position: static !important;
}

.sc-upload-multiple:deep(.el-upload--picture-card) {
  border-radius: 0;
}

.sc-upload-list-item {
  width: 100%;
  height: 100%;
  position: relative;
}

.sc-upload-multiple .el-image {
  display: block;
}

.sc-upload-multiple .el-image:deep(img) {
  -webkit-user-drag: none;
}

.sc-upload-multiple-image-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  font-size: 12px;
}

.sc-upload-multiple .el-upload-list__item:hover .sc-upload__item-actions {
  display: block;
}

.sc-upload__item-actions {
  position: absolute;
  top: 0;
  right: 0;
  display: none;
}

.sc-upload__item-actions span {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 25px;
  height: 25px;
  cursor: pointer;
  color: #fff;
}

.sc-upload__item-actions span i {
  font-size: 12px;
}

.sc-upload__item-actions .del {
  background: #f56c6c;
}

.sc-upload__item-progress {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  background-color: var(--el-overlay-color-lighter);
}
</style>
